package com.ndp.fb.rdb.mongo.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.WriteConcern;
import com.ndp.fb.constant.MongoConstants;
import com.ndp.fb.mongo.api.AdMarketTargetMongoService;
import com.ndp.fb.mongo.api.IMongodbService;
import com.ndp.fb.mongo.model.autocreatead.AdMarketTarget;
import com.ndp.fb.mongo.model.autocreatead.robot.AdInfoForStrategy;
import com.ndp.fb.mongo.model.autocreatead.robot.MarketingTargetStrategy;
import com.ndp.fb.rdb.model.Pager;

/**
 * Created by Elvis on 2016/6/6.
 */
@Service
public class AdMarketTargetMongoServiceImpl implements AdMarketTargetMongoService {

	Logger logger = LoggerFactory.getLogger(getClass());
	@Autowired
	private DB mongoDBClient;

	@Autowired
	private IMongodbService mongodbService;

	@Override
	public String save(AdMarketTarget adMarketTarget) {
		if (adMarketTarget == null) {
			logger.info("adMarketTarget入库对象为空，退出入库操作");
			return null;
		}
		try {
			DBObject dbObject = (DBObject) com.mongodb.util.JSON.parse(JSONObject.toJSONString(adMarketTarget));
			DBCollection dbCollection = mongoDBClient.getCollection(MongoConstants.TABLE_NAME_ADMARKETTARGET);
			dbCollection.save(dbObject, WriteConcern.JOURNALED);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
		logger.info("-----向mongoDB：" + MongoConstants.TABLE_NAME_ADMARKETTARGET + "集合插入数据完成");
		return adMarketTarget.getId();
	}

	@Override
	public List<AdMarketTarget> getAllList() {
		logger.info("获取全部adMarkettarget列表");
		DBCollection dbCollection = mongoDBClient.getCollection(MongoConstants.TABLE_NAME_ADMARKETTARGET);
		DBObject o = new BasicDBObject();
		o.put("status", 1);
		DBCursor dbCursor = dbCollection.find(o);
		if (dbCursor == null) {
			return null;
		}
		List<AdMarketTarget> adMarketTargets = new ArrayList<>();
		while (dbCursor.hasNext()) {
			adMarketTargets.add(JSONObject.parseObject(JSONObject.toJSONString(dbCursor.next()), AdMarketTarget.class));
		}
		return adMarketTargets;
	}

	@Override
	public void updateAdMarketTarget(AdMarketTarget adMarketTarget) {
		if (adMarketTarget == null) {
			logger.info("adMarketTarget对象为空，退出更新操作");
		}
		try {
			DBCollection collection = mongoDBClient.getCollection(MongoConstants.TABLE_NAME_ADMARKETTARGET);
			DBObject query = new BasicDBObject();
			query.put("id", adMarketTarget.getId());
			DBObject update = (DBObject) com.mongodb.util.JSON.parse(JSONObject.toJSONString(adMarketTarget));
			collection.update(query, update, true, false, WriteConcern.JOURNALED);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
		logger.info("-----向mongoDB：" + MongoConstants.TABLE_NAME_ADMARKETTARGET + "集合更新数据完成");
	}

	@Override
	public void updateAdMarketTargetStatus(String id, Integer status, String attribution) {
		try {
			DBCollection collection = mongoDBClient.getCollection(MongoConstants.TABLE_NAME_ADMARKETTARGET);
			DBObject query = new BasicDBObject();
			query.put("id", id);
			DBObject update = new BasicDBObject("status", status);
			update.put("attribution",attribution);
			collection.update(query, new BasicDBObject("$set", update), true, false);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
	}

	@Override
	public Pager<AdMarketTarget> getMarketTarget(Integer pageNum, Integer pageSize) {
		logger.info("adMarketTarget对象为空，退出获取广告目标列表操作");

		DBCollection dbCollection = mongoDBClient.getCollection(MongoConstants.TABLE_NAME_ADMARKETTARGET);
		DBObject dbObject = new BasicDBObject();
		dbObject.put("status", 1);
		long count = dbCollection.count(dbObject);
		DBCursor dbCursor = dbCollection.find(dbObject).limit(pageSize).skip((pageNum - 1) * pageSize);
		if (dbCursor == null) {
			return null;
		}
		List<AdMarketTarget> adMarketTargets = new ArrayList<>();
		while (dbCursor.hasNext()) {
			adMarketTargets.add(JSONObject.parseObject(JSONObject.toJSONString(dbCursor.next()), AdMarketTarget.class));
		}

		Pager<AdMarketTarget> pages = new Pager<AdMarketTarget>();
		pages.setResultList(adMarketTargets);
		pages.setTotalSize(count);
		pages.setPageSize(pageSize);
		pages.setPageIndex(pageNum);

		logger.info("adMarketTarget对象为空，退出获取广告目标操作");
		return pages;
	}

	@Override
	public void pushMarketingTargetStrategy(MarketingTargetStrategy marketingTargetStrategy, String adMarketTargetId) {
		DBCollection dbCollection = mongoDBClient.getCollection(MongoConstants.TABLE_NAME_ADMARKETTARGET);
		DBObject query = new BasicDBObject();
		query.put("id", adMarketTargetId);
		DBObject update = new BasicDBObject();
		DBObject dbObject = (DBObject) com.mongodb.util.JSON.parse(JSONObject.toJSONString(marketingTargetStrategy));
		update.put("$addToSet", new BasicDBObject("marketingTargetStrategies", dbObject));
		dbCollection.update(query, update, true, false, WriteConcern.JOURNALED);
	}

	@Override
	public void pushAdInfo(AdInfoForStrategy adInfoForStrategy, String strategyRuleSpecificId,
			String adMarketTargetId) {
		DBCollection dbCollection = mongoDBClient.getCollection(MongoConstants.TABLE_NAME_ADMARKETTARGET);
		DBObject query = new BasicDBObject();
		query.put("id", adMarketTargetId);
		query.put("marketingTargetStrategies.strategyRuleSpecificId", strategyRuleSpecificId);
		DBObject update = new BasicDBObject();
		DBObject dbObject = (DBObject) com.mongodb.util.JSON.parse(JSONObject.toJSONString(adInfoForStrategy));
		update.put("$addToSet", new BasicDBObject("marketingTargetStrategies.$.adInfoForStrategies", dbObject));
		dbCollection.update(query, update, true, false, WriteConcern.JOURNALED);
	}

	@Override
	public AdMarketTarget findByMarketingId(String mtId) {
		DBCollection dbCollection = mongoDBClient.getCollection(MongoConstants.TABLE_NAME_ADMARKETTARGET);
		DBObject query = new BasicDBObject();
		query.put("id", mtId);
		DBCursor dbCursor = dbCollection.find(query);
		AdMarketTarget r = null;
		if (dbCursor != null && dbCursor.hasNext()) {
			r = JSONObject.parseObject(JSONObject.toJSONString(dbCursor.next()), AdMarketTarget.class);
		}
		return r;
	}
	@Override
	public String saveAdMarketTargetParam(JSONObject param) {
		if (param == null) {
			logger.info("adMarketTargetPARAM入库对象为空，退出入库操作");
			return null;
		}
		try {
			param.put("id", UUID.randomUUID().toString());
			param.put("status", "wait");
			DBObject dbObject = (DBObject) com.mongodb.util.JSON.parse(JSONObject.toJSONString(param, SerializerFeature.DisableCircularReferenceDetect));
			DBCollection dbCollection = mongoDBClient.getCollection(MongoConstants.TABLE_NAME_ADMARKETTARGETPARAM);
			dbCollection.save(dbObject, WriteConcern.JOURNALED);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
		logger.info("-----向mongoDB：" + MongoConstants.TABLE_NAME_ADMARKETTARGET + "集合插入数据完成");
		return param.getString("id");
	}

	@Override
	public void updateAdMarketTargetParamStatus(String id, String status) {
		try {
			DBCollection collection = mongoDBClient.getCollection(MongoConstants.TABLE_NAME_ADMARKETTARGETPARAM);
			DBObject query = new BasicDBObject();
			query.put("id", id);
			DBObject update = new BasicDBObject("status", status);
			collection.update(query, new BasicDBObject("$set", update), true, false, WriteConcern.JOURNALED);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}

	}

	@Override
	public List<JSONObject> findWaitPublishAdMarketTargetParam() {
		DBCollection dbCollection = mongoDBClient.getCollection(MongoConstants.TABLE_NAME_ADMARKETTARGETPARAM);
		DBObject dbObject = new BasicDBObject();
		dbObject.put("status", "wait");
		DBCursor dbCursor = dbCollection.find(dbObject);
		if (dbCursor == null) {
			return null;
		}
		List<JSONObject> adMarketTargets = new ArrayList<>();
		while (dbCursor.hasNext()) {
			adMarketTargets.add(JSONObject.parseObject(JSONObject.toJSONString(dbCursor.next())));
		}

		return adMarketTargets;
	}

	@Override
	public void updateAdInfo(AdInfoForStrategy adInfoForStrategy,
			String adMarketTargetId) {
		AdMarketTarget adMarketTarget = this.findByMarketingId(adMarketTargetId);
		List<MarketingTargetStrategy> marketingTargetStrategies = adMarketTarget.getMarketingTargetStrategies();
		if(!CollectionUtils.isEmpty(marketingTargetStrategies)){
			for(MarketingTargetStrategy marketingTargetStrategy:marketingTargetStrategies){
				List<AdInfoForStrategy> adInfoForStrategies = marketingTargetStrategy.getAdInfoForStrategies();
				if(!CollectionUtils.isEmpty(adInfoForStrategies)){
					for(int i=0;i<adInfoForStrategies.size();i++){
						if(adInfoForStrategy.getAdId().equals(adInfoForStrategies.get(i).getAdId())){
							DBCollection dbCollection = mongoDBClient.getCollection(MongoConstants.TABLE_NAME_ADMARKETTARGET);
							DBObject query = new BasicDBObject();
							query.put("id", adMarketTargetId);
							query.put("marketingTargetStrategies.strategyRuleSpecificId", marketingTargetStrategy.getStrategyRuleSpecificId());
							DBObject update = new BasicDBObject();
							DBObject dbObject = (DBObject) com.mongodb.util.JSON.parse(JSONObject.toJSONString(adInfoForStrategy));
							DBObject updateObj = new BasicDBObject();
							for(String key:dbObject.keySet()){
								updateObj.put("marketingTargetStrategies.$.adInfoForStrategies."+i+"."+key, dbObject.get(key));
							}
							update.put("$set", updateObj);
							dbCollection.update(query, update, true, false, WriteConcern.JOURNALED);
						}
					}
				}
			}
		}

	}

	@Override
	public List<AdMarketTarget> getAdMarketTargetByFeedId(Long wefeedId) {
		logger.info("获取指定feed下的adMarkettarget列表");
		DBCollection dbCollection = mongoDBClient.getCollection(MongoConstants.TABLE_NAME_ADMARKETTARGET);
		DBObject o = new BasicDBObject();
		o.put("feedWeId", wefeedId);
		DBCursor dbCursor = dbCollection.find(o);
		if (dbCursor == null) {
			return null;
		}
		List<AdMarketTarget> adMarketTargets = new ArrayList<>();
		while (dbCursor.hasNext()) {
			adMarketTargets.add(JSONObject.parseObject(JSONObject.toJSONString(dbCursor.next()), AdMarketTarget.class));
		}
		return adMarketTargets;
	}
}
